﻿using LeaderCCSLaserUI.Data;
using LeaderCCSLaserUI.Data.Extensions;
using Newtonsoft.Json;
using NLog;
using Prism.Commands;
using Prism.Ioc;
using Prism.Mvvm;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ModuleMektecMES.ViewModels
{
    public class MESMainViewModel : NavigationViewModel
    {
        #region 变量
        string oeeConnectString = "http://192.168.208.101/iot-api/v1/";
        private RestClient oeeClient;
        string mesConnectString = "http://SUZAPI:9201/";
        private RestClient mesClient;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        TimeSpan delatime = new TimeSpan(0);
        string partNum = string.Empty;
        #endregion
        #region 属性
        private string messageStr = string.Empty;
        public string MessageStr
        {
            get { return messageStr; }
            set { SetProperty(ref messageStr, value); }
        }
        private bool isUseOEE;
        public bool IsUseOEE
        {
            get { return isUseOEE; }
            set { SetProperty(ref isUseOEE, value); }
        }
        private string oEE_ID;
        public string OEE_ID
        {
            get { return oEE_ID; }
            set { SetProperty(ref oEE_ID, value); }
        }
        private bool isUseMES;
        public bool IsUseMES
        {
            get { return isUseMES; }
            set { SetProperty(ref isUseMES, value); }
        }
        private string productModel;
        public string ProductModel
        {
            get { return productModel; }
            set { SetProperty(ref productModel, value); }
        }
        private string lotNo;
        public string LotNo
        {
            get { return lotNo; }
            set { SetProperty(ref lotNo, value); }
        }
        private string product;
        public string Product
        {
            get { return product; }
            set { SetProperty(ref product, value); }
        }
        private string barcode;
        public string Barcode
        {
            get { return barcode; }
            set { SetProperty(ref barcode, value); }
        }
        private string lineName;
        public string LineName
        {
            get { return lineName; }
            set { SetProperty(ref lineName, value); }
        }
        private string _operator;
        public string Operator
        {
            get { return _operator; }
            set { SetProperty(ref _operator, value); }
        }
        private string machine;
        public string Machine
        {
            get { return machine; }
            set { SetProperty(ref machine, value); }
        }
        private string engineerID;
        public string EngineerID
        {
            get { return engineerID; }
            set { SetProperty(ref engineerID, value); }
        }
        private string subEngineerID;
        public string SubEngineerID
        {
            get { return subEngineerID; }
            set { SetProperty(ref subEngineerID, value); }
        }
        private string ext1;
        public string Ext1
        {
            get { return ext1; }
            set { SetProperty(ref ext1, value); }
        }
        private string ext2;
        public string Ext2
        {
            get { return ext2; }
            set { SetProperty(ref ext2, value); }
        }
        #endregion
        #region 命令
        private DelegateCommand testButtonCommand;
        public DelegateCommand TestButtonCommand =>
            testButtonCommand ?? (testButtonCommand = new DelegateCommand(ExecuteTestButtonCommand));
        private DelegateCommand loadedEventCommand;
        public DelegateCommand LoadedEventCommand =>
            loadedEventCommand ?? (loadedEventCommand = new DelegateCommand(ExecuteLoadedEventCommand));
        private DelegateCommand<object> textBoxLostFocusCommand;
        public DelegateCommand<object> TextBoxLostFocusCommand =>
            textBoxLostFocusCommand ?? (textBoxLostFocusCommand = new DelegateCommand<object>(ExecuteTextBoxLostFocusCommand));
        private DelegateCommand<object> oEESwitchCommand;
        public DelegateCommand<object> OEESwitchCommand =>
            oEESwitchCommand ?? (oEESwitchCommand = new DelegateCommand<object>(ExecuteOEESwitchCommand));
        private DelegateCommand<Object> mESSwitchCommand;
        public DelegateCommand<Object> MESSwitchCommand =>
            mESSwitchCommand ?? (mESSwitchCommand = new DelegateCommand<Object>(ExecuteMESSwitchCommand));

        void ExecuteMESSwitchCommand(Object obj)
        {
            if (obj is bool r)
            {
                using var mdb = new MDbContext(partNum);
                var param = mdb.MParams.FirstOrDefault(p => p.Name == "IsUseMES");
                if (param != null)
                {
                    param.Value = IsUseMES.ToString();
                }
                else
                {
                    mdb.MParams.Add(new MParam { Name = "IsUseMES", Value = IsUseMES.ToString(), Type = typeof(bool).Name, Hand = 0 });
                }
                mdb.SaveChanges();
            }
        }
        void ExecuteOEESwitchCommand(object obj)
        {
            if (obj is bool r)
            {
                using var mdb = new MDbContext(partNum);
                var param = mdb.MParams.FirstOrDefault(p => p.Name == "IsUseOEE");
                if (param != null)
                {
                    param.Value = IsUseOEE.ToString();
                }
                else
                {
                    mdb.MParams.Add(new MParam { Name = "IsUseOEE", Value = IsUseOEE.ToString(), Type = typeof(bool).Name, Hand = 0 });
                }
                mdb.SaveChanges();
            }
        }
        void ExecuteTextBoxLostFocusCommand(object obj)
        {
            if (obj is string str)
            {
                switch (str)
                {
                    case "OEE_ID":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "OEE_ID");
                            if (param != null)
                            {
                                param.Value = OEE_ID;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "OEE_ID", Value = OEE_ID, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "ProductModel":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "ProductModel");
                            if (param != null)
                            {
                                param.Value = ProductModel;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "ProductModel", Value = ProductModel, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "LotNo":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "LotNo");
                            if (param != null)
                            {
                                param.Value = LotNo;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "LotNo", Value = LotNo, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "Product":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "Product");
                            if (param != null)
                            {
                                param.Value = Product;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "Product", Value = Product, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "Barcode":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "Barcode");
                            if (param != null)
                            {
                                param.Value = Barcode;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "Barcode", Value = Barcode, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "LineName":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "LineName");
                            if (param != null)
                            {
                                param.Value = LineName;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "LineName", Value = LineName, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "Operator":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "Operator");
                            if (param != null)
                            {
                                param.Value = Operator;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "Operator", Value = Operator, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "Machine":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "Machine");
                            if (param != null)
                            {
                                param.Value = Machine;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "Machine", Value = Machine, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "EngineerID":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "EngineerID");
                            if (param != null)
                            {
                                param.Value = EngineerID;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "EngineerID", Value = EngineerID, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "SubEngineerID":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "SubEngineerID");
                            if (param != null)
                            {
                                param.Value = SubEngineerID;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "SubEngineerID", Value = SubEngineerID, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "Ext1":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "Ext1");
                            if (param != null)
                            {
                                param.Value = Ext1;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "Ext1", Value = Ext1, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    case "Ext2":
                        {
                            using var mdb = new MDbContext(partNum);
                            var param = mdb.MParams.FirstOrDefault(p => p.Name == "Ext2");
                            if (param != null)
                            {
                                param.Value = Ext2;
                            }
                            else
                            {
                                mdb.MParams.Add(new MParam { Name = "Ext2", Value = Ext2, Type = typeof(string).Name, Hand = 0 });
                            }
                            mdb.SaveChanges();
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        void ExecuteLoadedEventCommand()
        {
            try
            {
                if (IsUseOEE)
                {
                    var r = Execute_GetOeeTime(new BaseRequest { Route = "time", Method = Method.Get });
                    if (r == null)
                    {
                        addMessage("OEE连接失败");
                    }
                }
            }
            catch (Exception ex)
            {
                addMessage(ex.Message);
            }
        }
        void ExecuteTestButtonCommand()
        {
            //var ss = DateTime.Now.ToString();
            //var ti = Convert.ToDateTime("2023-06-12T12:07:34.730925+08:00");
            ProductionInfo _product = new ProductionInfo {
                ProductModel = ProductModel,
                LotNo = LotNo,
                Product = Product,
                Barcode = Barcode,
                LineName = LineName,
                Operator = Operator,
                Machine = Machine,
                EngineerID = EngineerID,
                SubEngineerID = SubEngineerID,
                Ext1 = Ext1,
                Ext2 = Ext2,
                Status = "0"
            };
            Execute_WriteEngineerProductionData("apimmcs040/engineer/WriteEngineerProductionData", JsonConvert.SerializeObject(_product));
        }
        #endregion

        public MESMainViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            oeeClient = new RestClient(oeeConnectString);
            mesClient = new RestClient(mesConnectString);
            aggregator.ResgiterMessage(arg =>
            {
                try
                {
                    var strs = arg.Message.Split(new char[] { ';' });

                    switch (strs[0])
                    {
                        case "PartNum":
                            {
                                partNum = strs[1];
                                using var mdb = new MDbContext(partNum);
                                var param = mdb.MParams.FirstOrDefault(p => p.Name == "OEE_ID");
                                if (param != null)
                                {
                                    OEE_ID = param.Value;
                                }
                                else
                                {
                                    OEE_ID = "CCS-LaserWelding";
                                    mdb.MParams.Add(new MParam { Name = "OEE_ID", Value = OEE_ID, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "IsUseOEE");
                                if (param != null)
                                {
                                    IsUseOEE = bool.Parse(param.Value);
                                }
                                else
                                {
                                    IsUseOEE = true;
                                    mdb.MParams.Add(new MParam { Name = "IsUseOEE", Value = IsUseOEE.ToString(), Type = typeof(bool).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }

                                param = mdb.MParams.FirstOrDefault(p => p.Name == "IsUseMES");
                                if (param != null)
                                {
                                    IsUseMES = bool.Parse(param.Value);
                                }
                                else
                                {
                                    IsUseMES = true;
                                    mdb.MParams.Add(new MParam { Name = "IsUseMES", Value = IsUseMES.ToString(), Type = typeof(bool).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "ProductModel");
                                if (param != null)
                                {
                                    ProductModel = param.Value;
                                }
                                else
                                {
                                    ProductModel = "I_NIOCCS";
                                    mdb.MParams.Add(new MParam { Name = "ProductModel", Value = ProductModel, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "LotNo");
                                if (param != null)
                                {
                                    LotNo = param.Value;
                                }
                                else
                                {
                                    LotNo = "33957117010";
                                    mdb.MParams.Add(new MParam { Name = "LotNo", Value = LotNo, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "Product");
                                if (param != null)
                                {
                                    Product = param.Value;
                                }
                                else
                                {
                                    Product = "LDR_0";
                                    mdb.MParams.Add(new MParam { Name = "Product", Value = Product, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "Barcode");
                                if (param != null)
                                {
                                    Barcode = param.Value;
                                }
                                else
                                {
                                    Barcode = "55065100810A772313080012C";
                                    mdb.MParams.Add(new MParam { Name = "Barcode", Value = Barcode, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "LineName");
                                if (param != null)
                                {
                                    LineName = param.Value;
                                }
                                else
                                {
                                    LineName = "A3-A-07";
                                    mdb.MParams.Add(new MParam { Name = "LineName", Value = LineName, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "Operator");
                                if (param != null)
                                {
                                    Operator = param.Value;
                                }
                                else
                                {
                                    Operator = "112T01";
                                    mdb.MParams.Add(new MParam { Name = "Operator", Value = Operator, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "Machine");
                                if (param != null)
                                {
                                    Machine = param.Value;
                                }
                                else
                                {
                                    Machine = "LDR_01";
                                    mdb.MParams.Add(new MParam { Name = "Machine", Value = Machine, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "EngineerID");
                                if (param != null)
                                {
                                    EngineerID = param.Value;
                                }
                                else
                                {
                                    EngineerID = "ATD01";
                                    mdb.MParams.Add(new MParam { Name = "EngineerID", Value = EngineerID, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "SubEngineerID");
                                if (param != null)
                                {
                                    SubEngineerID = param.Value;
                                }
                                else
                                {
                                    SubEngineerID = "F1-LASER-1";
                                    mdb.MParams.Add(new MParam { Name = "SubEngineerID", Value = SubEngineerID, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "Ext1");
                                if (param != null)
                                {
                                    Ext1 = param.Value;
                                }
                                else
                                {
                                    Ext1 = string.Empty;
                                    mdb.MParams.Add(new MParam { Name = "Ext1", Value = Ext1, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                                param = mdb.MParams.FirstOrDefault(p => p.Name == "Ext2");
                                if (param != null)
                                {
                                    Ext2 = param.Value;
                                }
                                else
                                {
                                    Ext2 = string.Empty;
                                    mdb.MParams.Add(new MParam { Name = "Ext2", Value = Ext2, Type = typeof(string).Name, Hand = 0 });
                                    mdb.SaveChanges();
                                }
                            }
                            break;
                        //投入数量:INPUT;1
                        //正常加工:PROCESSING;-
                        //产出数量:OUTPUT;2
                        //等待进板:WAIT_FOR_INPUT;-
                        //加工时间:CT;2
                        case "复位完成":
                            if (IsUseOEE)
                            {
                                addMessage("OEE:WAIT_FOR_INPUT");
                                var _time = Execute_GetOeeTime(new BaseRequest { Route = "time", Method = Method.Get });
                                List<OEEItem> _items = new List<OEEItem>();
                                _items.Add(new OEEItem
                                {
                                    code = "WAIT_FOR_INPUT",
                                    value = "1",
                                    time = _time
                                });
                                Execute_OeeUpload(new BaseRequest
                                {
                                    Route = "value",
                                    Method = Method.Post,
                                    Parameter = new OEE
                                    {
                                        id = OEE_ID,
                                        time = _time,
                                        items = _items
                                    }
                                });
                            }
                            break;
                        case "开始工作":
                            if (IsUseOEE)
                            {
                                addMessage("OEE:PROCESSING");
                                var _time = Execute_GetOeeTime(new BaseRequest { Route = "time", Method = Method.Get });
                                List<OEEItem> _items = new List<OEEItem>();
                                _items.Add(new OEEItem
                                {
                                    code = "PROCESSING",
                                    value = "1",
                                    time = _time
                                });
                                Execute_OeeUpload(new BaseRequest
                                {
                                    Route = "value",
                                    Method = Method.Post,
                                    Parameter = new OEE
                                    {
                                        id = OEE_ID,
                                        time = _time,
                                        items = _items
                                    }
                                });
                            }
                            break;
                        case "UPLOAD":
                            if (IsUseOEE)
                            {
                                addMessage("OEE:UPLOAD");
                                var _time = Execute_GetOeeTime(new BaseRequest { Route = "time", Method = Method.Get });
                                List<OEEItem> _items = new List<OEEItem>();
                                _items.Add(new OEEItem
                                {
                                    code = "INPUT",
                                    value = strs[2],
                                    time = _time
                                });
                                _items.Add(new OEEItem
                                {
                                    code = "OUTPUT",
                                    value = strs[2],
                                    time = _time
                                });
                                _items.Add(new OEEItem
                                {
                                    code = "CT",
                                    value = strs[3],
                                    time = _time
                                });
                                Execute_OeeUpload(new BaseRequest
                                {
                                    Route = "value",
                                    Method = Method.Post,
                                    Parameter = new OEE
                                    {
                                        id = OEE_ID,
                                        time = _time,
                                        items = _items
                                    }
                                });
                            }
                            if (IsUseMES)
                            {
                                ProductionInfo _product = new ProductionInfo
                                {
                                    ProductModel = ProductModel,
                                    LotNo = LotNo,
                                    Product = Product,
                                    Barcode = strs[1],
                                    LineName = LineName,
                                    Operator = Operator,
                                    Machine = Machine,
                                    EngineerID = EngineerID,
                                    SubEngineerID = SubEngineerID,
                                    Ext1 = Ext1,
                                    Ext2 = Ext2,
                                    Status = "0"
                                };
                                Execute_WriteEngineerProductionData("apimmcs040/engineer/WriteEngineerProductionData", JsonConvert.SerializeObject(_product));
                            }
                            break;
                        default:
                            break;
                    }
                }
                catch (Exception ex)
                {
                    addMessage(ex.Message);
                }
       
            }, "MES");
        }
        #region 功能函数
        private void addMessage(string str)
        {
            logger.Debug("MES:" + str);
            string[] s = MessageStr.Split('\n');
            if (s.Length > 1000)
            {
                MessageStr = "";
            }
            if (MessageStr != "")
            {
                MessageStr += "\n";
            }
            MessageStr += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " " + str;
        }
        string Execute_GetOeeTime(BaseRequest baseRequest)
        {
            var request = new RestRequest(baseRequest.Route, baseRequest.Method);
            //request.AddHeader("Content-Type", baseRequest.ContentType);
            var response = oeeClient.Execute(request);
            if (response.StatusCode == HttpStatusCode.OK)
            {
                addMessage(response.Content);
                string[] strs = response.Content.Split('[');
                delatime = Convert.ToDateTime(strs[0]) - DateTime.Now;
                return strs[0];
            }
            return null;
        }
        void Execute_OeeUpload(BaseRequest baseRequest)
        {
            var request = new RestRequest(baseRequest.Route, baseRequest.Method);
            request.AddHeader("Content-Type", baseRequest.ContentType);
            if (baseRequest.Parameter != null)
                request.AddParameter("application/json", JsonConvert.SerializeObject(baseRequest.Parameter), ParameterType.RequestBody);
            var response = oeeClient.Execute(request);
            if (response.StatusCode == HttpStatusCode.Created)
            {
                addMessage(response.Content);
            }
            else
            {
                addMessage("OEE上传失败");
            }
        }
        void Execute_WriteEngineerProductionData(string route, string productionInfo, string memo = "test")
        {
            var request = new RestRequest(route);
            request.AddParameter("Memo", memo);
            request.AddParameter("ProductionInfo", productionInfo);
            var response = mesClient.Execute(request);
            if (response.StatusCode == HttpStatusCode.OK)
            {
                addMessage(response.Content);
            }
            else {
                addMessage("MES上传失败");
            }
        }
        #endregion
    }
    public class BaseRequest
    {
        public Method Method { get; set; }
        public string Route { get; set; }
        public string ContentType { get; set; } = "application/json";
        public object Parameter { get; set; }
    }
    public class OEEItem
    {
        public string code { get; set; }
        public string value { get; set; }
        public string time { get; set; }
    }

    public class OEE
    {
        public string id { get; set; }
        public string time { get; set; }
        public List<OEEItem> items { get; set; }
    }
    public class ProductionInfo
    {
        public string ProductModel { get; set; }
        public string LotNo { get; set; }
        public string Product { get; set; }
        public string Barcode { get; set; }
        public string LineName { get; set; }
        public string Operator { get; set; }
        public string Machine { get; set; }
        public string EngineerID { get; set; }
        public string SubEngineerID { get; set; }
        public string Ext1 { get; set; }
        public string Ext2 { get; set; }
        public string Status { get; set; }
    }
}
